﻿using System;
using System.Windows.Input;

namespace BitsOfStuff
{
    /// <summary>
    /// Primitive datatype for point
    /// </summary>
    public struct MyPoint
    {
        private int _index;
        private double _x;

        /// <summary>
        /// X coordinate
        /// </summary>
        public double X
        {
            get
            {
                return _x;
            }
        }

        /// <summary>
        /// Y coordinate
        /// </summary>
        public double Y
        {
            get
            {
                return _y;
            }
        }

        private double _y;

        /// <summary>
        /// Function for returning value of X position
        /// </summary>
        /// <returns>X position</returns>
        public double getX()
        {
            return _x;
        }

        /// <summary>
        /// Function for returning value of Y position
        /// </summary>
        /// <returns>Y position</returns>
        public double getY()
        {
            return _y;
        }

        /// <summary>
        /// Function for setting X position
        /// </summary>
        /// <param name="x">X position</param>
        public void setX(double x)
        {
            _x = x;
        }

        /// <summary>
        /// Function for setting Y position
        /// </summary>
        /// <param name="index">Y position</param>
        public void setIndex(int index)
        {
            _index = index;
        }

        /// <summary>
        /// Vale of whitch point in row is it
        /// </summary>
        /// <returns>index</returns>
        public int getIndex()
        {
            return _index;
        }

        /// <summary>
        /// Function for setting Y position
        /// </summary>
        /// <param name="y">Y position</param>
        public void setY(double y)
        {
            _y = y;
        }

        /// <summary>
        /// Function for transform stylusPoint to ourPoint
        /// </summary>
        /// <param name="stylusPoint">Stylus point</param>
        public void create(StylusPoint stylusPoint)
        {
            _x = stylusPoint.X;
            _y = stylusPoint.Y;
        }

        /// <summary>
        /// Function for creating point from two parameters
        /// </summary>
        /// <param name="x">X value</param>
        /// <param name="y">Y value</param>
        public void create(double x, double y)
        {
            _x = x;
            _y = y;
        }

        /// <summary>
        /// Function for creating point, and then rotate that point aroutn another point and given angle
        /// </summary>
        /// <param name="x">X param</param>
        /// <param name="y">Y param</param>
        /// <param name="origin">Point of origin, point arout it we will rotate this point</param>
        /// <param name="angle">Angle of rotation</param>
        public void createAndRotate(double x, double y, MyPoint origin, double angle)
        {
            double radianAngle = angle * (Math.PI / 180);

            _x = Math.Cos(radianAngle) * (x - origin.getX()) -
                 Math.Sin(radianAngle) * (y - origin.getY()) + origin.getX();

            _y = Math.Sin(radianAngle) * (x - origin.getX()) +
                 Math.Cos(radianAngle) * (y - origin.getY()) + origin.getY();
        }

        /// <summary>
        /// Function for transform our point to stylus point
        /// </summary>
        /// <returns>Same stylus point</returns>
        public StylusPoint toStylusPoint()
        {
            return new StylusPoint(_x, _y);
        }

        /// <summary>
        /// Function for size of point
        /// </summary>
        /// <returns>Distance of point from axle origin </returns>
        public double getPointLength()
        {
            double result = Math.Sqrt(Math.Pow(_x, 2) + Math.Pow(_y, 2));
            return result;
        }

        /// <summary>
        /// Function that give us distance this point from another point
        /// </summary>
        /// <param name="point">Far point</param>
        /// <returns>Distance of this point from Far point</returns>
        public double getDistanceToPoint(MyPoint point)
        {
            double powerResult = Math.Pow(_x - point.getX(), 2)
                                 + Math.Pow(_y - point.getY(), 2);

            return Math.Sqrt(powerResult);
        }

        /// <summary>
        /// Function for margint to point into one , avrg values are used
        /// </summary>
        /// <param name="myPoint">next point</param>
        /// <returns>new avrg point</returns>
        public MyPoint mergePoint(MyPoint myPoint)
        {
            var result = new MyPoint();
            result.create((myPoint.getX() + _x) / 2, (myPoint.getY() + _y) / 2);
            return result;
        }

        /// <summary>
        /// Constructor of point from stylus point
        /// </summary>
        /// <param name="point"></param>
        /// <returns></returns>
        public static MyPoint makePoint(StylusPoint point)
        {
            var result = new MyPoint();
            result.setX(point.X);
            result.setY(point.Y);
            return result;
        }
    }
}